package com.kede.api.order.service.impl;

import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.kede.api.ienum.AppIdTypeEnum;
import com.kede.api.ienum.UserMoneyType;
import com.kede.api.order.dto.ZhiGoodInfoDTO;
import com.kede.api.order.pojo.ZhiMoneyOrderPO;
import com.kede.api.order.service.IUserService;
import com.kede.api.order.service.IZhiOrderService;
import com.kede.api.order.utils.OrderUtil;
import com.kede.dictenum.BoolDictEnum;
import com.kede.domain.*;
import com.kede.ienum.zhi.ZhiOrderStatusEnum;
import com.kede.ienum.zhi.ZhiOrderTypeEnum;
import com.kede.pojo.ResHttp;
import com.kede.pojo.ZhiTypeEnum;
import com.kede.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;

/***
 ** @Author:Pr.li
 ** @Description:
 ** @Date: create in 2023/6/12 10:28
 ***/
@Service
@Slf4j
public class ZhiOrderManageServiceImpl implements IZhiOrderService {


    @Resource
    private ZhiOrderGoodsListService zhiOrderGoodsListService;

    @Resource
    private ZhiOrderService zhiOrderService;

    @Resource
    private UsersService usersService;

    @Resource
    private ZhiUserCertifiedService zhiUserCertifiedService;

    @Resource
    private ConfigService configService;

    @Resource
    private IUserService iUserService;

    @Resource
    private ZhiGoodValidFailService zhiGoodValidFailService;

    @Resource
    private UserScoreLogService userScoreLogService;

    /**
     * 这里的数据需要脱敏，给大众看的 很容易泄露数据
     * @param ZhiGoodId
     * @return
     */
    @Override
    public ResHttp getZhiGoodDetailInfoById(Integer ZhiGoodId) {
        ZhiOrderGoodsListDomain byId = zhiOrderGoodsListService.getById(ZhiGoodId);
        if(ObjectUtil.isNull(byId)){
            return ResHttp.fail();
        }
        ZhiGoodInfoDTO zhiGoodInfoDTO = new ZhiGoodInfoDTO();
        zhiGoodInfoDTO.setZhiOrderGoodsListDomain(byId);

        LambdaQueryWrapper<ZhiOrderDomain> zhiOrderDomainLambdaQueryWrapper = new LambdaQueryWrapper<>();
        zhiOrderDomainLambdaQueryWrapper.eq(ZhiOrderDomain::getOrderSn,byId.getOrderSn());
        ZhiOrderDomain zhiorder = zhiOrderService.getOne(zhiOrderDomainLambdaQueryWrapper);
        zhiGoodInfoDTO.setZhiOrderDomain(zhiorder);

        UsersDomain usersDomain = usersService.getById(byId.getUserId());
        zhiGoodInfoDTO.setUsersDomain(usersDomain);

        ZhiUserCertifiedDomain zhiUserCertifiedDomain = zhiUserCertifiedService.getOneByUserId(byId.getStoreId());
        zhiGoodInfoDTO.setUserCertifiedDomain(zhiUserCertifiedDomain);
        return ResHttp.okData(zhiGoodDetailInfoDesensitization(zhiGoodInfoDTO));
    }

    /**
     * ZhiGoodInfoDTO 脱敏
     * @param zhiGoodInfoDTO
     * @return
     */
    private static ZhiGoodInfoDTO zhiGoodDetailInfoDesensitization(ZhiGoodInfoDTO zhiGoodInfoDTO){

        ZhiOrderGoodsListDomain zhiOrderGoodsListDomain = zhiGoodInfoDTO.getZhiOrderGoodsListDomain();
        zhiOrderGoodsListDomain.setId(0);
        zhiOrderGoodsListDomain.setStoreId(0);
        zhiOrderGoodsListDomain.setUserId(0);

        ZhiOrderDomain zhiOrderDomain = zhiGoodInfoDTO.getZhiOrderDomain();
        if(!ObjectUtil.isNull(zhiOrderDomain)){
            zhiOrderDomain.setUserId(0);
            zhiOrderDomain.setCertifiedId(0);
            zhiOrderDomain.setIds("");
            zhiOrderDomain.setStoreId(0);
        }

        ZhiUserCertifiedDomain userCertifiedDomain = zhiGoodInfoDTO.getUserCertifiedDomain();
        if(!ObjectUtil.isNull(userCertifiedDomain)){
            userCertifiedDomain.setId(0);
            userCertifiedDomain.setUserId(0);
            userCertifiedDomain.setMoney(new BigDecimal("0"));
            userCertifiedDomain.setMobile(DesensitizedUtil.mobilePhone(userCertifiedDomain.getMobile()));
        }


        UsersDomain usersDomain = zhiGoodInfoDTO.getUsersDomain();
        if(!ObjectUtil.isNull(usersDomain)){
            usersDomain.setIntegral(new BigDecimal("0"));
            usersDomain.setUsersPhone(DesensitizedUtil.mobilePhone(usersDomain.getUsersPhone()));
            usersDomain.setId(0);
            usersDomain.setAdminId(0);
            usersDomain.setOpenid("");
            usersDomain.setXcxOpenid("");
            usersDomain.setXcxStoreOpenid("");
            usersDomain.setXcxShiOpenid("");
            usersDomain.setXcxRiderOpenid("");
            usersDomain.setXcxQuOpenid("");
            usersDomain.setAppRiderOpenid("");
            usersDomain.setUserMoney(new BigDecimal("0"));
            usersDomain.setCountMoney(new BigDecimal("0"));
            usersDomain.setResidueMoney(new BigDecimal("0"));
            usersDomain.setWithdrawMoney(new BigDecimal("0"));
            usersDomain.setPassword("");
            usersDomain.setPayPwd("");
        }

        return zhiGoodInfoDTO;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResHttp addZhiMoneyOrder(ZhiMoneyOrderPO zhiMoneyOrderPO) {
        Long time = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8));
        //用户下单
        if(zhiMoneyOrderPO.getUserType().equals(AppIdTypeEnum.USER_XCX.getPhpType())){
            String orderSn = OrderUtil.getRandomNo(ZhiTypeEnum.MONEY.getOrderKey());
            ZhiOrderDomain zhiOrderDomain = new ZhiOrderDomain();
            zhiOrderDomain.setOrderSn(orderSn);
            zhiOrderDomain.setUserId(zhiMoneyOrderPO.getUserId());
            zhiOrderDomain.setAddressId(zhiMoneyOrderPO.getAddressId());
            zhiOrderDomain.setStoreId(zhiMoneyOrderPO.getStoreId());
            zhiOrderDomain.setCreatetime(time.intValue());
            zhiOrderDomain.setStarttime(zhiMoneyOrderPO.getStartTime());
            zhiOrderDomain.setEndtime(zhiMoneyOrderPO.getEndTime());
            zhiOrderDomain.setStatus(ZhiOrderStatusEnum.WAIT);
            zhiOrderDomain.setOrderType(ZhiOrderTypeEnum.MONTY);
            BigDecimal total = new BigDecimal("0");
            for (ZhiOrderGoodsListDomain good : zhiMoneyOrderPO.getGoodList()) {
                good.setOrderSn(orderSn);
                good.setStatus(ZhiOrderStatusEnum.WAIT.getCode());
                good.setUserId(zhiMoneyOrderPO.getUserId());
                good.setStoreId(zhiMoneyOrderPO.getStoreId());
                good.setCreatetime(time.intValue());
                total = good.getDefaultUserMoney().add(total);
            }
            zhiOrderDomain.setOrderMoney(total);
            zhiOrderService.save(zhiOrderDomain);
            zhiOrderGoodsListService.saveBatch(zhiMoneyOrderPO.getGoodList());
            //获取门店信息
            ZhiUserCertifiedDomain oneByUserId = zhiUserCertifiedService.getOneByUserId(zhiMoneyOrderPO.getStoreId());
            return ResHttp.okData(oneByUserId);
            //门店下单  门店自己的物品可以下单到自己的门店
        }else if(zhiMoneyOrderPO.getUserType().equals(AppIdTypeEnum.MENDIAN_XCX.getPhpType())){
            String orderSn = OrderUtil.getRandomNo(ZhiTypeEnum.STOREOWN.getOrderKey());
            ZhiOrderDomain zhiOrderDomain = new ZhiOrderDomain();
            zhiOrderDomain.setOrderSn(orderSn);
            zhiOrderDomain.setUserId(zhiMoneyOrderPO.getUserId());
            zhiOrderDomain.setStoreId(zhiMoneyOrderPO.getStoreId());
            zhiOrderDomain.setCreatetime(time.intValue());
            zhiOrderDomain.setStatus(ZhiOrderStatusEnum.FINISH);
            zhiOrderDomain.setOrderType(ZhiOrderTypeEnum.MONTY);
            BigDecimal total = new BigDecimal("0");
            for (ZhiOrderGoodsListDomain good : zhiMoneyOrderPO.getGoodList()) {
                good.setOrderSn(orderSn);
                good.setStatus(ZhiOrderStatusEnum.FINISH.getCode());
                good.setUserId(zhiMoneyOrderPO.getUserId());
                good.setStoreId(zhiMoneyOrderPO.getStoreId());
                good.setCreatetime(time.intValue());
                total = good.getDefaultStoreMoney().add(total);
            }
            zhiOrderDomain.setOrderMoney(total);
            zhiOrderService.save(zhiOrderDomain);
            zhiOrderGoodsListService.saveBatch(zhiMoneyOrderPO.getGoodList());
            //添加门店验收款
            ZhiUserCertifiedDomain store = zhiUserCertifiedService.getOneByUserId(zhiMoneyOrderPO.getStoreId());
            BigDecimal validMoney = store.getValidMoney().add(total);
            store.setValidMoney(validMoney);
            zhiUserCertifiedService.updateById(store);
            return ResHttp.ok();
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResHttp addZhiOrder(ZhiMoneyOrderPO zhiMoneyOrderPO) {
        Long time = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8));
        String orderKey = "";
        if (zhiMoneyOrderPO.getType().equals(ZhiTypeEnum.DEBI.getCode())){
            orderKey = ZhiTypeEnum.DEBI.getOrderKey();
        }else if(zhiMoneyOrderPO.getType().equals(ZhiTypeEnum.MONEY.getCode())){
            orderKey = ZhiTypeEnum.MONEY.getOrderKey();
        }else if(zhiMoneyOrderPO.getType().equals(ZhiTypeEnum.DEBIWEIGHT.getCode())){
            orderKey = ZhiTypeEnum.DEBIWEIGHT.getOrderKey();
        }else{
            return ResHttp.failMsg("type 类型错误");
        }
        System.out.println("===========\n"+zhiMoneyOrderPO.getUserType());
        //用户下单
        if(zhiMoneyOrderPO.getUserType().equals(AppIdTypeEnum.USER_XCX.getPhpType())){
            String orderSn = OrderUtil.getRandomNo(orderKey);
            ZhiOrderDomain zhiOrderDomain = new ZhiOrderDomain();
            zhiOrderDomain.setOrderSn(orderSn);
            zhiOrderDomain.setUserId(zhiMoneyOrderPO.getUserId());
            zhiOrderDomain.setAddressId(zhiMoneyOrderPO.getAddressId());
            zhiOrderDomain.setStoreId(zhiMoneyOrderPO.getStoreId());
            zhiOrderDomain.setCreatetime(time.intValue());

            zhiOrderDomain.setStarttime(zhiMoneyOrderPO.getStartTime());
            zhiOrderDomain.setEndtime(zhiMoneyOrderPO.getEndTime());
            zhiOrderDomain.setStatus(ZhiOrderStatusEnum.WAIT);
            zhiOrderDomain.setOrderType(ZhiOrderTypeEnum.ZHI);
            BigDecimal totalRMB = new BigDecimal("0");
            BigDecimal totalDebi = new BigDecimal("0");
            for (ZhiOrderGoodsListDomain good : zhiMoneyOrderPO.getGoodList()) {
                good.setOrderSn(orderSn);
                good.setStatus(ZhiOrderStatusEnum.WAIT.getCode());
                good.setUserId(zhiMoneyOrderPO.getUserId());
                good.setStoreId(zhiMoneyOrderPO.getStoreId());
                good.setCreatetime(time.intValue());
                if(ObjectUtil.isNull(good.getDefaultUserDebi())){
                    good.setDefaultUserDebi(new BigDecimal("0"));
                }
                good.setScore(good.getDefaultUserDebi());
                good.setMoney(good.getDefaultUserMoney());
                if(good.getDefaultUserMoney().compareTo(new BigDecimal("-1")) > 0){
                    totalRMB = good.getDefaultUserMoney().add(totalRMB);
                }
                totalDebi = good.getDefaultUserDebi().add(totalDebi);
            }
            zhiOrderDomain.setScore(totalDebi);
            zhiOrderDomain.setOrderMoney(totalRMB);
            zhiOrderService.save(zhiOrderDomain);
            zhiOrderGoodsListService.saveBatch(zhiMoneyOrderPO.getGoodList());
            //获取门店信息
            ZhiUserCertifiedDomain oneByUserId = zhiUserCertifiedService.getOneByUserId(zhiMoneyOrderPO.getStoreId());
            return ResHttp.okData(oneByUserId);
            //门店下单  门店自己的物品可以下单到自己的门店
        }else if(zhiMoneyOrderPO.getUserType().equals(AppIdTypeEnum.MENDIAN_XCX.getPhpType())){
            String orderSn = OrderUtil.getRandomNo(ZhiTypeEnum.STOREOWN.getOrderKey());
            ZhiOrderDomain zhiOrderDomain = new ZhiOrderDomain();
            zhiOrderDomain.setOrderSn(orderSn);
            zhiOrderDomain.setUserId(zhiMoneyOrderPO.getUserId());
            zhiOrderDomain.setStoreId(zhiMoneyOrderPO.getStoreId());
            zhiOrderDomain.setCreatetime(time.intValue());
            zhiOrderDomain.setStatus(ZhiOrderStatusEnum.FINISH);
            zhiOrderDomain.setOrderType(ZhiOrderTypeEnum.MONTY);
            BigDecimal total = new BigDecimal("0");
            for (ZhiOrderGoodsListDomain good : zhiMoneyOrderPO.getGoodList()) {
                good.setOrderSn(orderSn);
                good.setStatus(ZhiOrderStatusEnum.FINISH.getCode());
                good.setUserId(zhiMoneyOrderPO.getUserId());
                good.setStoreId(zhiMoneyOrderPO.getStoreId());
                good.setCreatetime(time.intValue());
                total = good.getDefaultStoreMoney().add(total);
            }
            zhiOrderDomain.setOrderMoney(total);
            zhiOrderService.save(zhiOrderDomain);
            zhiOrderGoodsListService.saveBatch(zhiMoneyOrderPO.getGoodList());
            //添加门店验收款
            ZhiUserCertifiedDomain store = zhiUserCertifiedService.getOneByUserId(zhiMoneyOrderPO.getStoreId());
            BigDecimal validMoney = store.getValidMoney().add(total);
            store.setValidMoney(validMoney);
            zhiUserCertifiedService.updateById(store);
            return ResHttp.ok();
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResHttp storeConfirm(Integer goodId) {
        try{
            ZhiOrderGoodsListDomain byId = zhiOrderGoodsListService.getById(goodId);
            if (byId == null){
                return ResHttp.failMsg("goodId 参数错误");
            }
            if(!byId.getStatus().equals(ZhiOrderStatusEnum.ING.getCode())){
                return ResHttp.failMsg("改商品已经置换过 参数错误");
            }
            byId.setStatus(ZhiOrderStatusEnum.FINISH.getCode());
            zhiOrderGoodsListService.updateById(byId);
            boolean orderCanFinish = orderCanIsFinish(byId);
            log.debug("orderCanFinish=={}",orderCanFinish);
            if (orderCanFinish){
                LambdaUpdateWrapper<ZhiOrderDomain> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.set(ZhiOrderDomain::getStatus,ZhiOrderStatusEnum.FINISH.getEnumIndex());
                updateWrapper.eq(ZhiOrderDomain::getOrderSn,byId.getOrderSn());
                log.debug("getOrderSn=={}",byId.getOrderSn());
                zhiOrderService.update(updateWrapper);
            }
            //处理置换数
            UsersDomain user = usersService.getById(byId.getUserId());
            user.setZhiMoneyNum(user.getZhiMoneyNum() + 1);
            usersService.updateById(user);
            //处理钱
            iUserService.actionMoney(byId.getUserId(),byId.getDefaultUserMoney(),byId.getOrderSn(), UserMoneyType.ZHI);
            //添加门店验收款
            ZhiUserCertifiedDomain store = zhiUserCertifiedService.getOneByUserId(byId.getStoreId());
            BigDecimal validMoney = store.getValidMoney().add(byId.getDefaultStoreMoney());
            store.setValidMoney(validMoney);
            zhiUserCertifiedService.updateById(store);
            return ResHttp.ok();
        }catch (Exception e){
            e.printStackTrace();
            log.debug("storeConfirm出现错误",e.getMessage());
            throw e;
        }


    }

    @Override
    public ResHttp delZhiOrder(String orderSn) {
        LambdaUpdateWrapper<ZhiOrderDomain> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(ZhiOrderDomain::getIsDelete, BoolDictEnum.TRUE.getCode());
        updateWrapper.eq(ZhiOrderDomain::getOrderSn,orderSn);
        zhiOrderService.update(updateWrapper);
        return ResHttp.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResHttp confirmZhiOrder(Integer goodId) {
        ZhiOrderGoodsListDomain good = zhiOrderGoodsListService.getById(goodId);
        if (good == null){
            return ResHttp.failMsg("goodId 参数错误");
        }
        if(!good.getStatus().equals(ZhiOrderStatusEnum.ING.getCode())){
            return ResHttp.failMsg("改商品已经置换过 参数错误");
        }
        good.setStatus(ZhiOrderStatusEnum.FINISH.getCode());
        zhiOrderGoodsListService.updateById(good);
        boolean orderCanFinish = orderCanIsFinish(good);
        log.debug("orderCanFinish=={}",orderCanFinish);
        if (orderCanFinish){
            LambdaUpdateWrapper<ZhiOrderDomain> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(ZhiOrderDomain::getStatus,ZhiOrderStatusEnum.FINISH.getEnumIndex());
            updateWrapper.eq(ZhiOrderDomain::getOrderSn,good.getOrderSn());
            log.debug("getOrderSn=={}",good.getOrderSn());
            zhiOrderService.update(updateWrapper);
        }
        //用户
        UsersDomain user = usersService.getById(good.getUserId());
        BigDecimal score = good.getScore();
        if (user.getIsVip().equals(BoolDictEnum.TRUE.getCode())){
            //Vip 返回双倍积分
            score = score.multiply(new BigDecimal("2"));
        }
        if(good.getDefaultUserMoney().compareTo(BigDecimal.ZERO) > 0){
            iUserService.actionMoney(good.getUserId(),good.getDefaultUserMoney(), good.getOrderSn(), UserMoneyType.ZHI);
        }
        AddDebiAndRecord(user,score,good.getDefaultUserMoney());
        //添加门店验收款
        ZhiUserCertifiedDomain store = zhiUserCertifiedService.getOneByUserId(good.getStoreId());
        BigDecimal validMoney = store.getValidMoney().add(good.getDefaultStoreMoney());
        store.setValidMoney(validMoney);
        zhiUserCertifiedService.updateById(store);
        return ResHttp.ok();
    }

    @Override
    public boolean AddDebiAndRecord(UsersDomain user, BigDecimal score,BigDecimal money) {
        BigDecimal add = user.getIntegral().add(score);
        //添加记录
        UserScoreLogDomain scoreLogDomain = UserScoreLogDomain.builder()
        .after(add)
        .before(user.getIntegral())
        .userId(user.getId())
        .score(score)
        .changeType(1)//与php 一致
        .memo("确认置换增加积分").build();
        boolean a = userScoreLogService.save(scoreLogDomain);
        user.setIntegral(add);
        boolean b = usersService.updateById(user);
        return a && b;
    }

    /**
     * 根据订单中的一个物品 判断父订单是否可以是 已完成 的状态
     * @param good
     * @return
     */
    public boolean orderCanIsFinish(ZhiOrderGoodsListDomain good){
        String orderSn = good.getOrderSn();
        LambdaQueryWrapper<ZhiOrderGoodsListDomain> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ZhiOrderGoodsListDomain::getOrderSn,orderSn);
        queryWrapper.eq(ZhiOrderGoodsListDomain::getStatus, ZhiOrderStatusEnum.ING);
        int count = zhiOrderGoodsListService.count(queryWrapper);
        log.debug("orderCanIsFinish.count=={}",count);
        return count==0;
    }

}
